package com.example.demo.service;

import com.example.demo.mapper.TimerSettingsMapper;

import com.example.demo.model.entity.TimerSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

@Service
public class TimerTaskService {
    private static final Logger logger = LoggerFactory.getLogger(TimerTaskService.class);

    @Autowired
    private TimerSettingsMapper timerSettingsMapper;

    @Autowired
    private TaskScheduler taskScheduler;

    @Autowired
    private DeviceService deviceService;

    private Map<String, ScheduledFuture<?>> scheduledTasks = new HashMap<>();

    @PostConstruct
    public void initializeTasks() {
        refreshTimerTasks();
    }

    public void refreshTimerTasks() {
        logger.info("开始刷新定时任务");
        // 取消所有现有的定时任务
        scheduledTasks.values().forEach(task -> task.cancel(false));
        scheduledTasks.clear();

        // 重新加载所有定时设置并创建新的定时任务
        List<TimerSettings> allSettings = timerSettingsMapper.selectList(null);
        for (TimerSettings settings : allSettings) {
            scheduleTask(settings);
        }
        logger.info("定时任务刷新完成，共加载 {} 个任务", allSettings.size());
    }

    private void scheduleTask(TimerSettings settings) {
        if (!settings.getEnabled()) {
            logger.info("定时器未启用，跳过任务调度。设备: {}, 继电器: {}", settings.getImei(), settings.getRelayType());
            return; // 如果定时器未启用，不创建定时任务
        }

        String cronExpressionOn = createCronExpression(settings.getOnTime(), settings.getRepeat());
        String cronExpressionOff = createCronExpression(settings.getOffTime(), settings.getRepeat());

        ScheduledFuture<?> taskOn = taskScheduler.schedule(
                () -> executeTask(settings, true),
                new CronTrigger(cronExpressionOn)
        );

        ScheduledFuture<?> taskOff = taskScheduler.schedule(
                () -> executeTask(settings, false),
                new CronTrigger(cronExpressionOff)
        );

        scheduledTasks.put(settings.getImei() + "_" + settings.getRelayType() + "_on", taskOn);
        scheduledTasks.put(settings.getImei() + "_" + settings.getRelayType() + "_off", taskOff);

        logger.info("成功调度任务。设备: {}, 继电器: {}, 开启时间: {}, 关闭时间: {}",
                settings.getImei(), settings.getRelayType(), settings.getOnTime(), settings.getOffTime());
    }

    private void executeTask(TimerSettings settings, boolean isOn) {
        String action = isOn ? "开启" : "关闭";
        logger.info("执行{}任务，时间: {} 对于设备: {} 继电器: {}",
                action, java.time.LocalTime.now(), settings.getImei(), settings.getRelayType());

        try {
            // 构造设置设备属性的参数
            Map<String, Object> params = new HashMap<>();

            // 根据继电器类型和动作设置正确的开关参数
            switch (settings.getRelayType()) {
                case "main":
                    // 总开关：使用switch_0
                    params.put("switch_0", isOn);
                    break;
                case "relay1":
                    // 继电器1
                    params.put("switch_1", isOn);
                    break;
                case "relay2":
                    // 继电器2
                    params.put("switch_2", isOn);
                    break;
                default:
                    logger.warn("未知的继电器类型: {}", settings.getRelayType());
                    return;
            }

            // 调用DeviceService的setDeviceProperty方法
            deviceService.setDeviceProperty(settings.getProductId(), settings.getImei(), params)
                    .subscribe(
                            response -> logger.info("设置设备属性成功: {}", response),
                            error -> logger.error("设置设备属性失败: ", error)
                    );
        } catch (Exception e) {
            logger.error("执行定时任务时发生错误", e);
        }
    }

    private String createCronExpression(String time, String repeat) {
        String[] timeParts = time.split(":");
        String dayOfWeek = convertRepeatToCron(repeat);
        return String.format("0 %s %s ? * %s", timeParts[1], timeParts[0], dayOfWeek);
    }

    private String convertRepeatToCron(String repeat) {
        if (repeat == null || repeat.isEmpty()) {
            return "*"; // 默认每天
        }

        switch (repeat.toLowerCase()) {
            case "每天":
                return "*";
            case "周一":
                return "MON";
            case "周二":
                return "TUE";
            case "周三":
                return "WED";
            case "周四":
                return "THU";
            case "周五":
                return "FRI";
            case "周六":
                return "SAT";
            case "周日":
                return "SUN";
            default:
                // 处理多个日期的情况
                StringBuilder cronDays = new StringBuilder();
                if (repeat.contains("周一")) cronDays.append("MON,");
                if (repeat.contains("周二")) cronDays.append("TUE,");
                if (repeat.contains("周三")) cronDays.append("WED,");
                if (repeat.contains("周四")) cronDays.append("THU,");
                if (repeat.contains("周五")) cronDays.append("FRI,");
                if (repeat.contains("周六")) cronDays.append("SAT,");
                if (repeat.contains("周日")) cronDays.append("SUN,");

                // 移除最后的逗号
                if (cronDays.length() > 0) {
                    cronDays.setLength(cronDays.length() - 1);
                    return cronDays.toString();
                }

                // 如果没有匹配到任何日期，默认为每天
                return "*";
        }
    }
}